﻿using PmSoft.Data.Abstractions;
using System.Data;

namespace PmSoft.Data.PetaPoco;

/// <summary>
/// 基于 PetaPoco 的工作单元实现，用于统一管理数据库事务。
/// </summary>
/// <typeparam name="TDbContext">继承自 <see cref="PetaPocoDbContext"/> 的数据库上下文类型。</typeparam>
public class PetaPocoUnitOfWork<TDbContext> : IUnitOfWork
	where TDbContext : PetaPocoDbContext
{
	private readonly TDbContext _dbContext;

	/// <summary>
	/// 初始化工作单元实例。
	/// </summary>
	/// <param name="dbContext">PetaPoco 数据库上下文实例。</param>
	public PetaPocoUnitOfWork(TDbContext dbContext)
	{
		_dbContext = dbContext;
	}

	/// <summary>
	/// 同步开启数据库事务。
	/// </summary>
	/// <param name="isolationLevel">事务隔离级别（默认: <see cref="IsolationLevel.ReadCommitted"/>）。</param>
	public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
	{
		// 设置隔离级别后开启事务
		_dbContext.IsolationLevel = isolationLevel;
		_dbContext.BeginTransaction();
	}

	/// <summary>
	/// 异步开启数据库事务。
	/// </summary>
	/// <param name="isolationLevel">事务隔离级别（默认: <see cref="IsolationLevel.ReadCommitted"/>）。</param>
	/// <param name="cancellationToken">取消令牌，用于取消异步操作。</param>
	public async Task BeginTransactionAsync(
		IsolationLevel isolationLevel = IsolationLevel.ReadCommitted,
		CancellationToken cancellationToken = default)
	{
		_dbContext.IsolationLevel = isolationLevel;
		// 异步开启事务，并传递取消令牌
		await _dbContext.BeginTransactionAsync(cancellationToken).ConfigureAwait(false);
	}

	/// <summary>
	/// 同步提交事务。
	/// </summary>
	public void CommitTransaction()
	{
		// 提交事务并确认完成
		_dbContext.CompleteTransaction();
	}

	/// <summary>
	/// 异步提交事务。
	/// </summary>
	/// <param name="cancellationToken">取消令牌，用于取消异步操作。</param>
	public async Task CommitTransactionAsync(CancellationToken cancellationToken = default)
	{
		// 异步提交事务（假设 PetaPoco 支持异步提交）
		await _dbContext.CompleteTransactionAsync().ConfigureAwait(false);
	}

	/// <summary>
	/// 同步回滚事务。
	/// </summary>
	public void RollbackTransaction()
	{
		// 终止当前事务
		_dbContext.AbortTransaction();
	}

	/// <summary>
	/// 异步回滚事务。
	/// </summary>
	/// <param name="cancellationToken">取消令牌，用于取消异步操作。</param>
	public async Task RollbackTransactionAsync(CancellationToken cancellationToken = default)
	{
		// 异步终止事务（假设 PetaPoco 支持异步回滚）
		await _dbContext.AbortTransactionAsync().ConfigureAwait(false);
	}

	/// <summary>
	/// 释放数据库上下文资源。
	/// </summary>
	public void Dispose()
	{
		// 确保事务已回滚并释放连接
		_dbContext?.Dispose();
	}
}